feat(#617): remove godo (DigitalOcean SDK) from workflow core#654
Conversation
…T_PROTO step contracts Steps that declare STRICT_PROTO mode + InputMessage + OutputMessage but no ConfigMessage (e.g., step.eventbus.ack, step.eventbus.publish) failed engine initialization with: STRICT_PROTO contract for config message "" cannot use legacy Struct fallback: missing protobuf message name The step has no per-instance config schema — data flows through the input message. Engine now treats empty ConfigMessage as "no typed config", encodes cfg as legacy *structpb.Struct, returns nil typed payload. Plugin's typed factory reads from InputMessage as designed. Caught by BMW PR #278 image-launch smoke against v0.51.3 + eventbus v0.3.0 (steps.eventbus.{ack,publish,consume} have empty ConfigMessage). Test: TestCreateTypedConfigRequestEmptyConfigMessageStrictProto.
… non-nil cfg paths
Force-cutover single-PR plan: delete 11 legacy DO modules+steps (~3042 LOC), strip 8 registration sites, remove godo from go.mod, add load-time migration error pointing to workflow-plugin-digitalocean + infra.* IaC types. AWS SDK audit deferred to follow-up issue (will auto-progress after merge). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
C-1 fix: add step-type migration guard (5 step.do_* types) alongside the module-type guard; error message branches on plugin-loaded detection. I-1 fix: parity matrix split into per-step rows; step.do_logs and step.do_scale flagged as GAPs with pre-merge follow-up issues in workflow-plugin-digitalocean. I-2 fix: migration error has two branches — 'install plugin' vs 'config-only issue, plugin already loaded'. Minors: exact grep invocation in T4; dns.go typo; infra_apply_test.go:1990 added to T2 review list. Companion: wfctl modernize rules in scope of T5 (auto-rewrite YAML). Considered approaches: added Option B' (build tag fence — rejected). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
I-1: platform_doks_test.go (164 LOC) added to deletion inventory.
Total now 12 files / ~3206 LOC; T1 scope updated.
m-1: wfctl modernize flag corrected (--apply, not --write).
m-2: example/ sub-module go.mod also pins godo as indirect; T4 now runs
go mod tidy in both root and example/, plus a second grep over go.mod
files to catch residual indirect dependencies.
Cycle-1 fixes verified to hold.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
m-1: grep gates now !-prefixed to fail CI on match (|| true was silent no-op). m-2: plugin-loaded detection simplified to single factory-map lookup. m-3: workflow-scenarios migration sequencing constraint added. t-1: T2 file count 9→10. Cycle 3 verdict PASS (0 Critical / 0 Important / 3 Minor incorporated). Pipeline advances to writing-plans. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Single-PR force-cutover, 5 tasks:
T1: delete 12 legacy DO files (~3206 LOC)
T2: strip 10 registration sites + remap wfctl detection hooks
T3: add legacy-type migration error guards (module + step paths)
T4: go mod tidy + CI grep gate
T5: docs + CHANGELOG + migration guide + wfctl modernize rules + file
follow-up issues in workflow-plugin-digitalocean (logs/scale GAPs)
and workflow (AWS audit)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
C-1 fix: T3 engine test uses NewStdEngine(app, logger) + AddModuleType()
per engine.go:146,210; package workflow.
C-2 fix: T3 step test uses module.NewStepRegistry().Create() per
pipeline_step_registry.go:18,32.
I-1 fix: T2 test calls KnownModuleTypes() / KnownStepTypes() directly
(invented buildTypeRegistry() was never a thing).
I-2 fix: iacProviderLoaded is now sync/atomic.Bool with IsIaCProviderLoaded()
accessor — eliminates race with parallel tests under go test -race.
I-3 fix: gap-type modernize test covers all 3 gap types (do_logs, do_scale,
do_networking) — previously only first two.
m-1: acknowledged walkTypeNodes vs walkNodes duplication; documented intent.
m-2 fix: module.RemovedInVersion constant; no more v0.52.0 sprinkled in 7+ places.
m-3 fix: modernize/testdata/legacy-do-config.{,.expected}.yaml committed;
end-of-PR checklist points at it.
End-of-PR checklist: added mandatory `go test -race ./...`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
C-1 fix (scope-limit Option 2): modernize Fix only renames type:, does NOT
inject config.provider:digitalocean. Migration guide now has explicit
manual provider-add step + example YAML + error string user will see.
C-2 fix: cmd/wfctl/deploy.go added to T2 (platform.* prefix collector +
"no platform.* modules" error message — both updated to include infra.*).
I-1: newTestEngine intentional plugin omission documented.
I-2: T5 includes comment-hygiene cleanup for hasPlatformModules / isInfraType.
m-1 fix: newTestEngine uses mockLogger{} matching engine_test.go pattern.
m-2 fix: legacyDORemovedInVersion duplicated in modernize package (import
cycle prevents shared constant) with keep-in-sync comment.
m-3 fix: AWS issue body now derives in-scope list from a runtime grep
rather than copying speculative names.
Cycle 1 plan-phase fixes verified to hold.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
C-1 fix: drop redeclared mockLogger from engine_legacy_do_migration_test.go; reuse the existing in-package type from engine_test.go:482. C-2 fix: drop legacyDORemovedInVersion duplicate; no import cycle exists (verified via go list). modernize now imports module and uses module.RemovedInVersion directly. Single source of truth. I-1 fix: add TestLegacyDOStepError_PluginLoaded (was missing — only not-loaded branch was tested for steps). m-1 fix: actions/checkout@v5 → @v4 (repo standard). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
C-1 fix: extract shared constants/formatters to internal/legacydo leaf package. Earlier cycle's "no import cycle" claim was wrong: module→plugin→modernize is a real transitive chain (verified via go list -deps). modernize cannot import module. Both packages now import only the leaf legacydo package. I-1 fix: replace package-level atomic.Bool iacProviderLoaded global with StepRegistry instance field. Per-registry state; parallel tests can own fresh NewStepRegistry() instances; no global mutation between tests. Engine sets the field via r.SetIaCProviderLoaded(loaded) just before pipeline construction. I-2 fix: design doc drops the credential-registry-zero-DO-entries test (unimplementable — credentialResolvers is unexported). Rationale: registry is additive via init(); deleting file removes init() — self- evidencing. No API-surface-for-test added. m-1 fix: T2 spec includes rename of platformModules local variable to deployTargetModules in cmd/wfctl/deploy.go. Cycle 1/2/3 plan-phase fixes verified to hold. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
C-1 fix: schema.ValidateConfig fires at engine.go:400 BEFORE the factory
loop at :506. Removing legacy DO types from schema/schema.go alone
would cause the generic schema error to mask the actionable migration
message. T3 now appends legacydo.ModuleTypes + StepTypes to
schema.WithExtra{Module,Step}Types so schema passes them through to
the factory guard — the real rejection point.
I-1 fix: e.stepRegistry is interfaces.StepRegistrar; SetIaCProviderLoaded
is not on the interface. Plan now uses the type-assertion pattern
from engine.go:163,216 (matches precedent; interface NOT widened).
I-2 fix: stale "T3 introduces a package-level atomic" comment in the
end-of-PR checklist updated to reflect the per-registry instance field.
m-1 fix: legacyDORule() unexported (matches peers); test in internal
package modernize (matches sibling test files); external modernize
import dropped.
Cycle 1-4 plan-phase fixes verified to hold.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
C-1 fix (two parts):
- Phantom schema.WithExtraStepTypes: schema.ValidateConfig only checks
module types, not step types. Step migration guard at StepRegistry.Create
is correctly the sole gate. Step-types schema-injection sentence/loop
deleted from T3.
- wfctl validate path: cmd/wfctl/validate.go and ci_validate.go call
schema.ValidateConfig directly (not via engine.BuildFromConfig). Without
a hook, AC3 fails on these commands. T2 now includes both files: inject
legacydo.ModuleTypes into opts + add post-ValidateConfig legacy sweep
emitting legacydo.Format{Module,Step}Error.
I-1 fix: `if len(...) > 0 || true` replaced with unconditional code
(staticcheck SA4010 was a CI lint blocker).
m-1: cycle-5 history line referenced the now-removed step-types injection;
implicit fix via T3 edit.
Cycle 1-5 fixes verified to hold.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
C-1 fix: validate/ci_validate post-pass step sweep was incorrect — cfg.Pipelines is map[string]any (verified config/config.go:149), not a typed slice. T2 now uses yaml.Marshal/Unmarshal pattern matching engine.go configurePipelines. Also separates ciValidateFile's accumulating errs=append from validateFile's early-return. I-1 fix: added TestValidateFile_LegacyDOModule_ReturnsActionableError and TestCIValidateFile_LegacyDOStep_ReturnsActionableError to T2 to give AC3 automated coverage on the validate path. Cycle 1-6 fixes verified to hold. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
plan-scope-check.sh requires "### Task N:" headings (H3); plan was using H2. PR Grouping rows reference Task 1-5 and the body must match. Now passes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Removes 12 files / ~3206 LOC. Registration sites cleaned in T2. * platform_do_app.go + test * platform_do_database.go + test * platform_do_dns.go + test * platform_do_networking.go + test * platform_doks.go + test * cloud_account_do.go (DO credential resolvers + doClient()) * pipeline_step_do.go (5 DO App Platform step types) Adds godo_absent_test.go as a regression gate inside module/.
* plugins/platform: drop 5 module + 5 step factories and manifest entries.
* schema/*: drop 10 entries from module/step type lists + schema descriptions.
Update editor-schemas.golden.json to match.
* cmd/wfctl/type_registry.go: drop 10 legacy DO type entries.
* cmd/wfctl/{infra.go,deploy_providers.go,ci_run_dryrun.go}: remap
isContainerType and deployTargetTypes to remove platform.do_app.
* cmd/wfctl/deploy.go: extend prefix check to include infra.* + rename
platformModules → deployTargetModules + update error message.
* module/multi_region.go: rewrite DOKS multi-region hint to point at
infra.k8s_cluster + workflow-plugin-digitalocean.
* cmd/wfctl/infra_apply_test.go: replace platform.do_app negative-test
fixture with example.legacy_unknown synthetic type.
* cmd/wfctl/{validate.go,ci_validate.go}: inject legacydo.ModuleTypes into
schema opts + post-ValidateConfig sweep emits actionable migration errors.
* cmd/wfctl/deploy_test.go: update error message assertion.
Creates internal/legacydo/types.go (leaf package — stdlib only) with the
legacy-DO type maps and message formatters needed by T3's engine/step-registry
guards and this task's wfctl validate edits.
Adds legacy_do_types_removed_test.go (registry-absence regression gate) +
TestValidateFile_LegacyDOModule_ReturnsActionableError and
TestCIValidateFile_LegacyDOStep_ReturnsActionableError (validate-path AC3).
Adds legacydo.FormatModuleError + legacydo.FormatStepError (already in internal/legacydo from T2) and wires them into two rejection points: engine.go:508 (module path) — factory-loop guard now emits the actionable migration error for the 5 removed legacy DO module types, branching on whether iac.provider is already registered in the engine. pipeline_step_registry.go:Create (step path) — unknown-step guard now emits the actionable migration error for the 5 removed legacy DO step types, using the per-registry iacProviderLoaded field set via SetIaCProviderLoaded before pipeline construction. engine.go:393-398 — guarded WithExtraModuleTypes block replaced with unconditional injection that also includes legacydo.ModuleTypes so that schema.ValidateConfig passes legacy DO module types through to the factory-loop guard (schema rejection would mask the migration message). SetIaCProviderLoaded bridges the boolean from engine to module package via type assertion (interface deliberately NOT widened — no method burden on alternate StepRegistrar implementors). Each step type gets a per-step message; step.do_logs and step.do_scale carry GAP messages with workarounds because no 1:1 pipeline-step successor exists yet (follow-up issues in T5). Tests: 5 module × 2 branches + 5 step × 2 branches = 12 sub-cases. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* go mod tidy on root and example/ drops github.com/digitalocean/godo (direct from root, indirect from example/). * New CI job 'godo-banned' fails the build on any *.go import of godo OR any mention of godo in go.mod files. Excludes _worktrees, .worktrees, .claude (local agent state) and godo_absent_test.go (T1 regression gate that references the import path as a string literal, not an actual import). This satisfies acceptance criterion #4 (dependabot bumps target the provider repo, not workflow core). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* New modernize rule "legacy-do-types": auto-rewrites 5 module types and 3
of 5 step types to infra.*; flags but does not modify the two GAP step
types (step.do_logs, step.do_scale) and the 1→2 platform.do_networking
split. Registered in AllRules().
* testdata/legacy-do-config.yaml: smoke-test fixture exercising all 10
legacy types; testdata/legacy-do-config.expected.yaml: golden post-Fix
output (types renamed, GAP types preserved, provider NOT auto-injected).
* CHANGELOG: v0.52.0 BREAKING entry.
* docs/migrations/v0.52.0-godo-removal.md: full migration guide with
mapping tables, before/after YAML, error reference, rollback note.
workflow-plugin-digitalocean follow-up issue URLs wired in:
step.do_logs GAP → GoCodeAlone/workflow-plugin-digitalocean#107
step.do_scale GAP → GoCodeAlone/workflow-plugin-digitalocean#108
* DOCUMENTATION.md: replace 10 legacy DO rows with pointers to the plugin
and the migration guide.
* Comment hygiene: drop "legacy" framing from hasPlatformModules and
parseInfraResourceSpecs doc comments (both functions correctly handle
the surviving platform.kubernetes / platform.ecs module types).
Follow-up issues filed:
GoCodeAlone/workflow-plugin-digitalocean#107 — step.iac_logs GAP
GoCodeAlone/workflow-plugin-digitalocean#108 — step.iac_scale GAP
#653 — AWS SDK audit (continuation of #617)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…o-types T5 appended legacyDORule (id: legacy-do-types) to AllRules() but missed this counter test in cmd/wfctl/modernize_test.go. Single-line fix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Removes the legacy DigitalOcean IaC surface from workflow core (and its github.com/digitalocean/godo dependency), shifting DO functionality to workflow-plugin-digitalocean and adding actionable migration errors plus a wfctl modernize rule to help users update configs.
Changes:
- Deleted legacy
platform.do_*/platform.doksmodules andstep.do_*steps; removed godo from root + example modules. - Added migration guards/errors for legacy DO module + step types (engine + wfctl validate/ci validate + step registry).
- Added a CI “godo-banned” grep gate and documentation/migration guide updates.
Reviewed changes
Copilot reviewed 53 out of 55 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| schema/testdata/editor-schemas.golden.json | Removes legacy DO module/step schema entries from golden editor schema output. |
| schema/step_schema_builtins.go | Removes built-in step schemas for step.do_*. |
| schema/schema.go | Removes legacy DO types from the hardcoded known-type list. |
| schema/module_schema.go | Removes built-in module schemas and step descriptions for legacy DO types. |
| plugins/platform/plugin.go | Removes legacy DO module/step registrations from the core platform plugin. |
| plugins/platform/plugin_test.go | Updates expected factories to reflect removal of legacy DO factories. |
| plugin/external/adapter.go | Handles STRICT_PROTO/PROTO_WITH_LEGACY_STRUCT contracts with empty ConfigMessage by using legacy struct only. |
| plugin/external/adapter_test.go | Adds coverage for empty ConfigMessage contract behavior. |
| module/platform_doks.go | Deleted legacy DOKS module implementation (godo-based). |
| module/platform_doks_test.go | Deleted tests for legacy DOKS module. |
| module/platform_do_networking.go | Deleted legacy DO networking module implementation (godo-based). |
| module/platform_do_networking_test.go | Deleted tests for legacy DO networking module. |
| module/platform_do_dns.go | Deleted legacy DO DNS module implementation (godo-based). |
| module/platform_do_dns_test.go | Deleted tests for legacy DO DNS module. |
| module/platform_do_database.go | Deleted legacy DO database module implementation (godo-based). |
| module/platform_do_database_test.go | Deleted tests for legacy DO database module. |
| module/platform_do_app.go | Deleted legacy DO App Platform module implementation (godo-based). |
| module/platform_do_app_test.go | Deleted tests for legacy DO App Platform module and DO steps. |
| module/pipeline_step_do.go | Deleted legacy DO pipeline step implementations. |
| module/cloud_account_do.go | Deleted DO credential resolvers + godo client helper from core. |
| module/pipeline_step_registry.go | Adds legacy DO step-type guard with actionable migration error. |
| module/pipeline_step_legacy_do_migration_test.go | Adds tests asserting legacy DO step types produce actionable errors. |
| module/multi_region.go | Updates DigitalOcean multi-region error message to point to infra.* + DO plugin. |
| module/godo_absent_test.go | Adds regression test to ensure module package does not import godo. |
| internal/legacydo/types.go | Introduces leaf package with legacy type mappings + formatter helpers for migration errors. |
| engine.go | Allows legacy DO module types through schema validation and returns actionable migration errors when encountered; wires iacProviderLoaded into step registry. |
| engine_legacy_do_migration_test.go | Adds engine-level tests for legacy DO module migration errors (plugin loaded/unloaded branches). |
| cmd/wfctl/validate.go | Adds legacy DO module allow-listing for schema + post-validate sweep for actionable errors. |
| cmd/wfctl/ci_validate.go | Adds legacy DO module allow-listing for schema + accumulates actionable legacy DO module/step errors. |
| cmd/wfctl/type_registry.go | Removes legacy DO types from wfctl’s known type registry. |
| cmd/wfctl/legacy_do_types_removed_test.go | Adds tests ensuring legacy DO types are absent from the registry and validate/ci_validate emit actionable errors. |
| cmd/wfctl/infra.go | Removes legacy platform.do_app from container-type detection. |
| cmd/wfctl/infra_apply.go | Clarifies comments around what qualifies as platform.* modules. |
| cmd/wfctl/infra_apply_test.go | Replaces a legacy DO module fixture type with a synthetic unknown type. |
| cmd/wfctl/deploy.go | Expands deploy cloud scanning to include infra.* modules as deploy targets. |
| cmd/wfctl/deploy_test.go | Updates expected error text after deploy cloud change. |
| cmd/wfctl/deploy_providers.go | Removes platform.do_app from deploy target types. |
| cmd/wfctl/ci_run_dryrun.go | Removes platform.do_app from dry-run deploy target types. |
| cmd/wfctl/modernize_test.go | Asserts the new legacy-do-types modernize rule is registered. |
| modernize/modernize.go | Registers the new legacy DO modernize rule. |
| modernize/legacy_do_rule.go | Adds a rule that rewrites legacy DO module/step type: values to successors (and flags gaps). |
| modernize/legacy_do_rule_test.go | Adds unit tests for legacy DO rule rewrites and gap behavior. |
| modernize/testdata/legacy-do-config.yaml | Adds a sample legacy config fixture for modernization. |
| modernize/testdata/legacy-do-config.expected.yaml | Adds expected post-modernize fixture (types rewritten / gaps retained). |
| DOCUMENTATION.md | Replaces legacy DO module/step listings with guidance pointing to the DO plugin + migration guide. |
| docs/migrations/v0.52.0-godo-removal.md | Adds the migration guide for the godo/legacy DO removal. |
| CHANGELOG.md | Adds a v0.52.0 breaking-change entry describing the removal and migration path. |
| docs/plans/2026-05-13-issue-617-godo-removal.md.scope-lock | Adds scope-lock hash for the plan. |
| docs/plans/2026-05-13-issue-617-godo-removal-design.md | Adds design document for the cutover/removal. |
| go.mod | Removes github.com/digitalocean/godo and its transitive deps. |
| go.sum | Removes checksums for godo-related modules. |
| example/go.mod | Removes indirect godo deps from the example submodule. |
| example/go.sum | Removes checksums for godo-related modules in example submodule. |
| .github/workflows/ci.yml | Adds godo-banned CI job to prevent reintroducing godo in Go sources or go.mod files. |
⏱ Benchmark Results✅ No significant performance regressions detected. benchstat comparison (baseline → PR)
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
…gration guide step example step.do_deploy/status/destroy require different config keys in their successors (platform + state_store vs legacy app:) — auto-rewriting the type alone produces an invalid config. Mark step findings Fixable: false, remove step rewrites from Fix(), update testdata fixture and tests to reflect unchanged step types post-modernize. Also update FormatStepError to include required config keys in the migration error message, and fix the migration guide pipeline-step example to show the correct step.iac_apply config shape. Addresses Copilot review comments: - r3232996570: make step findings non-fixable (option a) - r3232996648: fix migration guide step example config shape - r3232996683: fix testdata fixture to leave step types unchanged - r3232996732: add required config keys to step migration error Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…step rewrites step.do_deploy/status/destroy are now flagged-not-rewritten (Fixable: false) because their successors use different config keys. Update the step mapping table Auto-fix column and the recipe description to match. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… false positives staticcheck SA5011 flags t.Fatal()/t.Fatalf() as non-terminating because testing.T.Fatal calls runtime.Goexit (not a panic/return), which staticcheck does not model as a definite exit. Adding an unreachable `return` statement after each t.Fatal in iac/conformance scenarios makes the nil-guard pattern unambiguous to static analysis: execution cannot reach the pointer dereference if result/res is nil. Affected files: - iac/conformance/scenario_delete_action.go - iac/conformance/scenario_grpc_roundtrip.go - iac/conformance/scenario_replace_cascade_preserves_dependents.go - iac/conformance/scenario_upsert_on_already_exists.go Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Fixed Lint failure (SA5011 nil-dereference false positives) in commit 3f90451. Added |
Two corrections from Copilot's second-pass review:
1. docs/migrations/v0.52.0-godo-removal.md: plugin install snippet used a
top-level `plugins:` sequence with `source:` which does not match the app
config schema (ExternalPluginDecl has no source field; PluginsConfig wraps
external under plugins.external:). Replace with the correct `wfctl plugin
install` CLI command + wfctl.yaml manifest form (WfctlPluginEntry has source).
2. module/godo_absent_test.go: `filepath.Glob("*.go")` is non-recursive and
only checks the current directory, not subdirectories. The comment claimed it
covered "no file under module/", which was misleading. Switch to
`filepath.WalkDir(".", ...)` to make the assertion match the comment's intent
and guard against future subdirectory additions.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Addressed Copilot round 2 review in commit d868c05:
|
Summary
Closes #617. Force-cutover removal of
github.com/digitalocean/godofrom workflow core. Five legacyplatform.do_*modules + fivestep.do_*pipeline steps +cloud_account_do.godeleted (~3206 LOC across 12 files). Load-time migration errors point users toworkflow-plugin-digitalocean+ the newinfra.*IaC type system.wfctl modernizerule rewrites legacy YAML types automatically.Design + Plan
docs/plans/2026-05-13-issue-617-godo-removal-design.md(3 cycles of adversarial review)docs/plans/2026-05-13-issue-617-godo-removal.md(8 cycles of plan-phase adversarial review + alignment-check + scope-lock)docs/plans/2026-05-13-issue-617-godo-removal.md.scope-lock(manifest hash 7fcc5df5…)Scope Manifest
Acceptance criteria
github.com/digitalocean/godofor IaC/App Platform behaviorworkflow-plugin-digitaloceanv0.12.0+wfctlerrors remain actionable when a legacy DO type is referenced (engine path +wfctl validate+wfctl ci validateall branched oniac.providerfactory loaded vs not-loaded)godo-bannedCI gate)Changes (per task)
platform_do_{app,database,dns,networking}.go+ tests,platform_doks.go+ test,cloud_account_do.go,pipeline_step_do.go. Addsmodule/godo_absent_test.goAST regression gate.cmd/wfctl/validate.go+ci_validate.golegacy-type injection + post-ValidateConfigsweep sowfctl validateproduces the actionable migration error rather than a generic schema error.internal/legacydoleaf package (constants + maps + formatters); engine module guard atengine.go:508; per-registryiacProviderLoadedfield onStepRegistry(no global, noatomic.Boolrace surface); 12 sub-cases × 2 plugin-loaded branches.go mod tidyin root +example/; new CI jobgodo-bannedwith!-prefixed greps over*.goandgo.modfiles. Rollback: revert commit + re-rungo mod tidy; no runtime effect after T1-T3 deletions.wfctl modernizerulelegacy-do-types(rewrites 4 module + 3 step types; flags 3 GAP types —platform.do_networking1→2 split,step.do_logs+step.do_scaleno successor);CHANGELOG.mdv0.52.0 BREAKING entry;docs/migrations/v0.52.0-godo-removal.md;DOCUMENTATION.mdupdate.Migration
Configs using legacy types now fail to load with an actionable error pointing to
workflow-plugin-digitalocean+ theinfra.*successor. Operators runwfctl modernize --apply <config.yaml>to auto-rewrite type fields, then manually addprovider: digitaloceanto each rewritten module'sconfig:(the modernize rule does not auto-inject the provider key — see migration guide for rationale + example YAML).Follow-up issues filed
workflow-plugin-digitalocean: tracking forstep.iac_logs(closesstep.do_logsmigration GAP)workflow-plugin-digitalocean: tracking forstep.iac_scale(closesstep.do_scalemigration GAP)workflow: AWS SDK audit (parallel pattern to Move provider SDK dependencies out of Workflow core #617 — RBAC/secrets/artifact stay; IaC drivers reviewed for plugin move)Test Plan
go test ./...— passes (2 failures:TestFallbackRuns,TestInfraMultiEnv_E2Eindependently verified pre-existing on origin/main; not regressions)go test -race ./...— passes! grep -rn --include="*.go" --exclude-dir=_worktrees --exclude-dir=.worktrees --exclude-dir=.claude "digitalocean/godo" .exits 0! grep -qH "digitalocean/godo" go.mod example/go.modexits 0go build ./cmd/wfctl ./cmd/servercleangodo-bannedjob passes (added in T4; verifies on first run)wfctl modernize --apply modernize/testdata/legacy-do-config.yamlmatcheslegacy-do-config.expected.yaml(smoke fixture)Note on commit count
The branch carries 2 pre-existing in-flight commits (d2b7529
fix: address Copilot review, 542d54bfix(plugin/external): empty ConfigMessage) that originate from prior PRs onmainahead oforigin/main. They will collapse on merge.🤖 Generated with Claude Code